#! /bin/bash
# Call this script to check the format every c[pp] & h[pp] file
# in the current and parent directories against the defined clang-format style.
#
# Returns
# 0 on success
# 1 on an incorrect format
# 2 is clang-format 8 could not be found 

# Detect version
if command -v clang-format-8 > /dev/null; then
    BINARY="clang-format-8"
elif command -v clang-format > /dev/null; then
    BINARY="clang-format"
    VERSION=$(clang-format --version | grep -o '[0-9]\+.[0-9]\+.[0-9]\+' | head -1 | cut -d '.' -f 1)
    if (( $VERSION != 8 )); then
        echo "clang-format version 8 expected, but ${VERSION} found!"
        echo "Please install a suffixed binary (clang-format-8) or install clang-format version 8."
        exit 2
    fi
else
    echo "clang-format not found!"
    echo "Please install clang-format version 8."
    exit 2
fi
echo "Using binary: $BINARY"

# Detect GNU parallel
if command -v parallel > /dev/null ; then
    echo "GNU parallel detected."
    HAS_PARALLEL=true
    PAROPS="--group "
    if [ -z "$CI" ]; then
      PAROPS="$PAROPS --bar"
    fi
else
    echo "Install GNU parallel to format in parallel."
    HAS_PARALLEL=false
fi

# Check C/C++
CFILES="$(find . -type f -name \*.hpp -or -name \*.h -or -name \*.cpp -or -name \*.c)"
echo "Checking $(echo "$CFILES" | wc -l) C/C++ files"
DIFFS=""
if $HAS_PARALLEL; then
    CMD="${BINARY} -style=file --output-replacements-xml {} | grep '<replacement ' > /dev/null && echo {}"
    CDIFFS="$( echo "$CFILES" | parallel $PAROPS "$CMD" )"
    [[ -n "$CDIFFS" ]] && DIFFS="$DIFFS $CDIFFS"
else
    for cfile in $CFILES; do
        ${BINARY} -style=file --output-replacements-xml $cfile | grep '<replacement ' > /dev/null
        RET=$?
        if [ $RET -eq 0 ]; then
            DIFFS="$DIFFS $cfile"
        fi
    done
fi

# Detect python
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
if command -v python3 > /dev/null; then
  PYCMD="python3"
elif command -v python3 > /dev/null; then
  PYCMD="python"
else
  echo "No python installation found. XML files will not be checked."
fi

if [ ! -z "$PYCMD" ]; then
  # Check XML
  XMLFILES=$(find . -not \( -path ./docs -prune \) -type f -name \*.xml)
  XMLFMT="$SCRIPTDIR/config-formatter"
  echo "Checking $(echo "$XMLFILES" | wc -l) XML files"
  if $HAS_PARALLEL; then
    CMD="${PYCMD} $XMLFMT {} | diff -q {} - > /dev/null || echo {}"
    XMLDIFFS="$( echo "$XMLFILES" | parallel $PAROPS "$CMD" )"
    [[ -n "$XMLDIFFS" ]] && DIFFS="$DIFFS $XMLDIFFS"
  else
    echo "Install GNU parallel to format in parallel."
    for xmlfile in $XMLFILES; do
      diff -q <(${PYCMD} $XMLFMT $xmlfile) $xmlfile > /dev/null
      RET=$?
      if [ ! $RET -eq 0 ]; then
        DIFFS="$DIFFS $xmlfile"
      fi
    done
  fi
fi

if [[ -n "$DIFFS" ]]; then
    echo "The following files are not formatted correctly:"
    for file in $DIFFS; do
        echo "$file"
    done
    exit 1
else
    echo "All files are formatted correctly"
    exit 0
fi
